package com.alex.cms.web.controllers;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.alex.cms.domain.CmsUser;
import com.alex.cms.request.UserPwdReq;
import com.alex.cms.service.ICmsArticleService;
import com.alex.cms.service.ICmsCommentService;
import com.alex.cms.service.ICmsUserService;
import com.alex.cms.web.constants.CMSConstants;
import com.alex.cms.web.enums.Gender;
import com.alex.cms.web.form.UserForm;
import com.alex.cms.web.vo.ArticleVo;
import com.alex.cms.web.vo.CommentVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bawei.common.utils.DateUtil;
import com.bawei.common.utils.StringUtil;

/**
 * <p>
 * 用户相关的API接口
 * </p>
 *
 * @author alex
 * @since 2019-09-11{
 * 
 */
@Controller
@RequestMapping("/user")
public class CmsUserController {

	@Autowired
	private ICmsUserService userService;

	@Autowired
	private ICmsCommentService commentService;
	@Autowired
	private ICmsArticleService articleService;

	/**
	 * 
	 * @Title: showRegPage
	 * @Description: 展示注册页面
	 * @return
	 * @return ModelAndView
	 */
	@RequestMapping(value = "/reg", method = RequestMethod.GET)
	public ModelAndView showRegPage() {
		ModelAndView mav = new ModelAndView("passport/reg");
		UserForm userForm = new UserForm();
		mav.addObject("userForm", userForm);
		return mav;
	}

	@RequestMapping(value = "/reg", method = RequestMethod.POST)
	public ModelAndView userRegister(UserForm userForm) {
		ModelAndView mav = new ModelAndView("redirect:/user/login");
		String message = "";
		// 判断用户是否为空
		if (userForm == null) {
			message = CMSConstants.REQUEST_PARAM_IS_NULL;
			mav.addObject("message", message);
			mav.setViewName("passport/reg");
			return mav;
		}
		// 判断用户名是否为空
		if (!StringUtil.isEmpty(userForm.getUsername())) {
			message = CMSConstants.USERNAME_IS_NULL;
			mav.addObject("message", message);
			mav.setViewName("passport/reg");
			return mav;
		}
		// 判断密码是否为空
		if (!StringUtil.isEmpty(userForm.getPassword())) {
			message = CMSConstants.PASSWORD_IS_NULL;
			mav.addObject("message", message);
			mav.setViewName("passport/reg");
			return mav;
		}
		// 判断确认密码是否为空
		if (!StringUtil.isEmpty(userForm.getRePassword())) {
			message = CMSConstants.REPASSWORD_IS_NULL;
			mav.addObject("message", message);
			mav.setViewName("passport/reg");
			return mav;
		}
		// 密码与确认密码不相符
		if (!userForm.getRePassword().equals(userForm.getPassword())) {
			message = CMSConstants.PASSWORD_REPASSWORD_IS_NOT_SAME;
			mav.addObject("message", message);
			mav.setViewName("passport/reg");
			return mav;
		}
		QueryWrapper<CmsUser> queryWrapper = new QueryWrapper<CmsUser>();
		System.out.println(changePwdByMD5(userForm.getPassword(), userForm.getUsername(), CMSConstants.MD5_CHARACTER));
		queryWrapper = queryWrapper.eq("username", userForm.getUsername()).eq("password", changePwdByMD5(userForm.getPassword(), userForm.getUsername(), CMSConstants.MD5_CHARACTER));
		List<CmsUser> list = userService.list(queryWrapper);
		if (!CollectionUtils.isEmpty(list)) {
			message = CMSConstants.USER_IS_EXIST;
			mav.addObject("message", message);
			mav.addObject("userForm", userForm);
			mav.setViewName("passport/login");
			return mav;
		}
		// 保存用户信息
		CmsUser user = new CmsUser();
		user.setUsername(userForm.getUsername());
		// 密码保存时需要加密，使用MD5加密
		user.setPassword(changePwdByMD5(userForm.getPassword(), userForm.getUsername(), CMSConstants.MD5_CHARACTER));
		user.setGender(userForm.getGender().ordinal());
		user.setNickname(userForm.getUsername());
		user.setLocked(false);
		user.setCreated(new Date());
		user.setUpdated(user.getCreated());
		user.setAvatar("");
		userService.saveOrUpdate(user);
		return mav;
	}

	/**
	 * 
	 * @Title: showLoginPage
	 * @Description: 展示登录页面
	 * @return
	 * @return ModelAndView
	 */
	@RequestMapping(value = "/login", method = RequestMethod.GET)
	public ModelAndView showLoginPage() {
		ModelAndView mav = new ModelAndView("passport/login");
		UserForm userForm = new UserForm();
		mav.addObject("userForm", userForm);
		return mav;
	}

	@RequestMapping(value = "/login", method = RequestMethod.POST)
	public ModelAndView login(UserForm userForm, HttpSession session) {
		ModelAndView mav = new ModelAndView("user-space/home");
		String message = "";
		// 判断用户名是否为空
		if (!StringUtil.isEmpty(userForm.getUsername())) {
			message = CMSConstants.USERNAME_IS_NULL;
			mav.addObject("message", message);
			mav.setViewName("passport/login");
			return mav;
		}
		// 判断密码是否为空
		if (!StringUtil.isEmpty(userForm.getPassword())) {
			message = CMSConstants.PASSWORD_IS_NULL;
			mav.addObject("message", message);
			mav.setViewName("passport/login");
			return mav;
		}
		// 根据前端传过来的用户名和密码，进行跟数据库匹配，数据一致就登录成功
		QueryWrapper<CmsUser> queryWrapper = new QueryWrapper<CmsUser>();
		System.out.println(changePwdByMD5(userForm.getPassword(), userForm.getUsername(), CMSConstants.MD5_CHARACTER));
		queryWrapper = queryWrapper.eq("username", userForm.getUsername()).eq("password", changePwdByMD5(userForm.getPassword(), userForm.getUsername(), CMSConstants.MD5_CHARACTER)).eq("locked", false);

		List<CmsUser> list = userService.list(queryWrapper);
		if (CollectionUtils.isEmpty(list)) {
			message = CMSConstants.USER_IS_NOT_EXIST;
			mav.addObject("message", message);
			mav.addObject("userForm", userForm);
			mav.setViewName("passport/login");
			return mav;
		}
		// 保存用户信息到session
		session.setAttribute(CMSConstants.LOGIN_USER, list.get(0));
		return mav;
	}

	/**
	 * 
	 * @Title: showUserProfile
	 * @Description: 个人设置
	 * @param userId
	 * @return
	 * @return ModelAndView
	 */
	@RequestMapping("/profile")
	public ModelAndView showUserProfile(@RequestParam(value = "userid", required = false) Integer userId, HttpSession session) {
		System.out.println("================" + userId);
		if (userId == null) {
			CmsUser user = (CmsUser) session.getAttribute(CMSConstants.LOGIN_USER);
			userId = user.getId();
		}
		// 指向哪个jsp，括号里是jsp的路径
		ModelAndView mav = new ModelAndView("/user-space/profile");
		UserForm userForm = new UserForm();
		// 根据用户ID获取cms的用户
		CmsUser user = userService.getById(userId);
		// 如果不为空，就给页面赋值
		if (user != null) {
			userForm.setUsername(user.getUsername());
			userForm.setGender(Gender.getGenderByOrdinal(user.getGender()));
			userForm.setBirthday(user.getBirthday() != null ? DateUtil.dateToString(user.getBirthday(), DateUtil.DATE_FORMAT_TYPE) : DateUtil.dateToString(new Date(), DateUtil.DATE_FORMAT_TYPE));
			userForm.setNickname(user.getNickname());
			userForm.setMobile(user.getMobile());
			userForm.setMail(user.getMail());
			userForm.setAddress(user.getAddress());
			userForm.setConstellation(user.getConstellation());
			userForm.setMotto(user.getMotto());
		}
		// 返回信息给ModelAndView
		mav.addObject("userForm", userForm);
		mav.addObject("id", userId);
		return mav;
	}

	/**
	 * 
	 * @Title: updateProfile
	 * @Description: 修改个人设置
	 * @param userform
	 * @return
	 * @return ModelAndView
	 */
	@RequestMapping(value = "/profile", method = RequestMethod.POST)
	public ModelAndView updateProfile(UserForm userform,HttpSession session) {
		// 指定跳转路径，重定向到个人主页
		ModelAndView mav = new ModelAndView("redirect:/user/home");
		String message = ""; 
		// cms的用户进行修改
		CmsUser user = new CmsUser();
		user.setBirthday(DateUtil.changeStringToDate(userform.getBirthday(), DateUtil.DATE_FORMAT_TYPE));
		user.setNickname(userform.getNickname());
		user.setGender(userform.getGender().ordinal());
		user.setUpdated(new Date());
		if(StringUtil.isEmpty(userform.getMobile())){
			if(!StringUtil.isMobile(userform.getMobile())){
				message = CMSConstants.USER_MOBILE_ERROR;
				mav.addObject("message",message);
				mav.addObject("userForm",userform);
				mav.setViewName("user-space/profile");
				return mav;
			}
			user.setMobile(userform.getMobile());
		}
		if(StringUtil.isEmpty(userform.getMobile())){
			if (!StringUtil.isEmail(userform.getMail())) {
				message = CMSConstants.USER_MAIL_ERROR;
				mav.addObject("message",message);
				mav.addObject("userForm",userform);
				mav.setViewName("user-space/profile");
				return mav;
			}
			user.setMail(userform.getMail());
		}
		user.setAddress(userform.getAddress());
		user.setConstellation(userform.getConstellation());
		user.setMotto(userform.getMotto());
		userService.update(user, new QueryWrapper<CmsUser>().eq("id", userform.getId()));
		//用户信息修改后删除session
		session.removeAttribute(CMSConstants.LOGIN_USER);
		return mav;
	}

	/**
	 * 
	 * @Title: showUserSpaceView
	 * @Description: 个人首页
	 * @return
	 * @return ModelAndView
	 */
	@RequestMapping("/home")
	public ModelAndView showUserSpaceView(HttpSession session) {
		ModelAndView mav = new ModelAndView("user-space/home");
		CmsUser user = (CmsUser) session.getAttribute(CMSConstants.LOGIN_USER);
		if (user == null) {
			mav.setViewName("redirect:/user/login");
			return mav;
		}
		
		// 根据用户ID获取本用户的所有文章
		QueryWrapper<ArticleVo> queryWrapper = new QueryWrapper<ArticleVo>();
		queryWrapper = queryWrapper.eq("user_id", user.getId());
		// 手动创建sql，返回一个articleVo的集合
		List<ArticleVo> articles = articleService.selectAllArticlesByUserId(queryWrapper);
		mav.addObject("blogs", articles);
		mav.addObject(CMSConstants.LOGIN_USER, user);
		return mav;
	}

	/**
	 * 
	 * @Title: logout
	 * @Description: 退出登陆
	 * @param session
	 * @return
	 * @return ModelAndView
	 */
	@RequestMapping("/logout")
	public ModelAndView logout(HttpSession session) {
		ModelAndView mav = new ModelAndView();
		// 清除session
		if (session != null) {
			session.removeAttribute(CMSConstants.LOGIN_USER);
		}
		// 跳转到登录页面
		mav.setViewName("redirect:/user/login");
		return mav;
	}

	/**
	 * 
	 * @Title: showCommentPage
	 * @Description: 评论信息
	 * @param session
	 * @return
	 * @return ModelAndView
	 */
	@RequestMapping("/comments")
	public ModelAndView showCommentPage(HttpSession session) {
		// 指定评论jsp
		ModelAndView mav = new ModelAndView("/user-space/comments");
		CmsUser user = (CmsUser) session.getAttribute(CMSConstants.LOGIN_USER);
		// 自定义评论sql，根据评论人的ID获取所有评论
		List<CommentVo> comments = commentService.selectAllCommentsByUserId(new QueryWrapper<CommentVo>().eq("cms_comment.user_id", user.getId()));
		mav.addObject("comments", comments);
		return mav;
	}

	@RequestMapping(value = "/profile/avatar", method = RequestMethod.GET)
	public ModelAndView showAvatar(HttpSession session) {
		ModelAndView mav = new ModelAndView("/user-space/avatar");
		CmsUser user = (CmsUser) session.getAttribute(CMSConstants.LOGIN_USER);
		CmsUser avatar = userService.getOne(new QueryWrapper<CmsUser>().eq("id", user.getId()));
		mav.addObject("user", avatar);
		return mav;
	}

	@RequestMapping(value = "/addAvatar", method = RequestMethod.POST)
	public ModelAndView updateAvatar(MultipartFile file, CmsUser user, HttpSession session) {
		ModelAndView mav = new ModelAndView("redirect:/user/home");
		try {
			if (!file.isEmpty()) {
				// 如果提交了文章图片，则在服务器上保存该图片
				String orginalFilename = file.getOriginalFilename();
				String suffixName = orginalFilename.substring(orginalFilename.lastIndexOf("."));
				String uploadFileName = UUID.randomUUID().toString() + suffixName;

				String uploadDir = session.getServletContext().getRealPath("/") + CMSConstants.FILE_SAVE_PATH;

				// 文件上传的目录
				File uploadFile = new File(uploadDir);

				if (!uploadFile.exists()) {
					uploadFile.mkdir();
				}
				// 要上传的文件
				uploadFile = new File(uploadDir + uploadFileName);

				file.transferTo(uploadFile);

				CmsUser cmsUser = (CmsUser) session.getAttribute(CMSConstants.LOGIN_USER);

				CmsUser avatar = userService.getOne(new QueryWrapper<CmsUser>().eq("id", cmsUser.getId()));
				if (avatar != null) {
					if(user.getAvatar() !=null){
						File deleteFile = new File(session.getServletContext().getRealPath("/") + user.getAvatar());
						// java.io.File的判断方法，判断文件是否存在
						if (deleteFile.exists()) {
							// java.io.File的删除方法
							deleteFile.delete();
						}
					}
					avatar.setAvatar(CMSConstants.FILE_SAVE_PATH + uploadFileName);

				}
				userService.saveOrUpdate(avatar);
				session.setAttribute(CMSConstants.LOGIN_USER, avatar);
			}
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return mav;
	}

	@RequestMapping("/articles")
	public ModelAndView getMyArticles(HttpSession session) {
		CmsUser user = (CmsUser) session.getAttribute(CMSConstants.LOGIN_USER);
		ModelAndView mav = new ModelAndView("redirect:/article/list?userid=" + user.getId());
		return mav;
	}
	
	@RequestMapping("/toEditPwd")
	public ModelAndView getEditPassword(HttpSession session) {
		CmsUser user = (CmsUser) session.getAttribute(CMSConstants.LOGIN_USER);
		ModelAndView mav = new ModelAndView("admin/user-password-edit");
		mav.addObject("id",user.getId());
		return mav;
	}
	
	@RequestMapping("/editPwd")
	public ModelAndView getEditPassword(UserPwdReq req) {
		ModelAndView mav = new ModelAndView("redirect:/user/login");
		return mav;
	}

	/**
	 * 
	 * @Title: changePwdByMD5
	 * @Description: 用于密码加密
	 * @param password
	 *            原始密码
	 * @param userName
	 *            用户名
	 * @param MD5Content
	 *            自定义的字符串，防止被解密
	 * @return
	 * @return String 加密后的密码
	 */
	private String changePwdByMD5(String password, String userName, String MD5Content) {
		String md5Password = "";
		String pwd = password + userName + MD5Content;
		md5Password = DigestUtils.md5DigestAsHex(pwd.getBytes());
		return md5Password;
	}
}
